package com.aphrodite.ui.widgets.barcode;

import java.util.Vector;

/**
 * Specific implementation of Module that allows the grouping of multiple
 * Modules into one parent module. <p/>Note: You should not instantiate this
 * class directly.
 * 
 * 
 */
class CompositeModule extends Module {
	private final Vector modules;

	/**
	 * Constructs a new Composite module that is initially empty.
	 */
	CompositeModule() {
		super(new int[0]);
		modules = new Vector();
	}

	/**
	 * Adds the given module to this composite module.
	 * 
	 * @param module
	 *            The module to add
	 */
	void add(Module module) {
		modules.addElement(module);
	}

	/**
	 * Draws the module to the given outputter at the specified origin. This
	 * actually draws each child module in turn.
	 * 
	 * @param output
	 *            The outputter to draw to
	 * @param x
	 *            The X component of the origin
	 * @param y
	 *            The Y component of the origin
	 * @param barWidth
	 * @param barHeight
	 * @return The total width drawn
	 */
	protected int draw(Output output, int x, int y, int barWidth, int barHeight) throws OutputException {
		int sum = 0;
		int currentX = x;
		for (int i = 0; i < modules.size(); i++) {
			Module module = (Module) modules.elementAt(i);
			int result = module.draw(output, currentX, y, barWidth, barHeight);
			currentX += result;
			sum += result;
		}
		// for (Iterator iterator = modules.iterator(); iterator.hasNext();) {
		// Module module = (Module) iterator.next();
		// int result = module.draw(output, currentX, y, barWidth, barHeight);
		// currentX += result;
		// sum += result;
		// }

		return sum;
	}

	/**
	 * Returns the child module at the specified index.
	 * 
	 * @param index
	 *            The module index
	 * @return The module at the given index
	 */
	Module getModule(int index) {
		return (Module) modules.elementAt(index);
	}

	/**
	 * Returns the symbol group encoded by this module. This is actually a
	 * concatenation of the symbols encoded by each child module.
	 * 
	 * @return The symbol encoded by this composite module
	 */
	String getSymbol() {
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < modules.size(); i++) {
			Module module = (Module) modules.elementAt(i);// .next();
			buf.append(module.getSymbol());
		}
		// for (Iterator iterator = modules.iterator(); iterator.hasNext();) {
		// Module module = (Module) iterator.next();
		// buf.append(module.getSymbol());
		// }
		return buf.toString();
	}

	/**
	 * Returns the number of modules currently contained within this composite
	 * module.
	 * 
	 * @return The number of child modules
	 */
	int size() {
		return modules.size();
	}

	/**
	 * Returns the underlying total width of the bars from the bar specification
	 * (that is, the sum of original bar widths in base bar units).
	 * 
	 * @return The total width of bars in base (unscaled) units
	 */
	int widthInBars() {
		int width = 0;
		for (int i = 0; i < modules.size(); i++) {// Iterator iterator =
			// modules.iterator();
			// iterator.hasNext();) {
			Module module = (Module) modules.elementAt(i);// .next();
			width += module.widthInBars();
		}
		// for (Iterator iterator = modules.iterator(); iterator.hasNext();) {
		// Module module = (Module) iterator.next();
		// width += module.widthInBars();
		// }
		return width;
	}
}
